import { Injectable, OnModuleInit } from '@nestjs/common';
import { DatabaseService } from '../database/database.service.js';
import type { PoolClient } from 'pg';

export interface TaskDto {
  id: string;
  title: string;
  description?: string | null;
  status: 'open' | 'done';
  created_at: string;
}

@Injectable()
export class TasksService implements OnModuleInit {
  constructor(private readonly db: DatabaseService) {}

  private async withClient<T>(fn: (c: PoolClient) => Promise<T>): Promise<T> {
    return this.db.useClient(fn);
  }

  onModuleInit(): void {
    // Run schema init in background to avoid blocking startup
    void this.initSchema().catch((err) => {
      // eslint-disable-next-line no-console
      console.error('TasksService schema init failed:', err);
    });
  }

  private async initSchema(): Promise<void> {
    await this.withClient(async (c) => {
      await c.query(`CREATE EXTENSION IF NOT EXISTS pgcrypto;`);
      await c.query(`
        CREATE TABLE IF NOT EXISTS mvp_tasks (
          id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
          title text NOT NULL,
          description text,
          status text NOT NULL DEFAULT 'open',
          created_at timestamptz NOT NULL DEFAULT now()
        );
      `);
    });
  }

  async list(): Promise<TaskDto[]> {
    return this.withClient(async (c) => {
      const { rows } = await c.query(
        'SELECT id, title, description, status, created_at FROM mvp_tasks ORDER BY created_at DESC'
      );
      return rows as TaskDto[];
    });
  }

  async create(input: { title: string; description?: string | null }): Promise<TaskDto> {
    return this.withClient(async (c) => {
      const { rows } = await c.query(
        'INSERT INTO mvp_tasks(title, description) VALUES($1,$2) RETURNING id, title, description, status, created_at',
        [input.title, input.description ?? null]
      );
      return rows[0] as TaskDto;
    });
  }

  async setDone(id: string): Promise<TaskDto | null> {
    return this.withClient(async (c) => {
      const { rows } = await c.query(
        "UPDATE mvp_tasks SET status = 'done' WHERE id = $1 RETURNING id, title, description, status, created_at",
        [id]
      );
      return rows[0] ?? null;
    });
  }
}
